package com.redfootdev.horseskills;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.plugin.java.JavaPlugin;



public class HorseDatabase extends Database {
	
	private JavaPlugin plugin;
	
	//
	// These strings are used as the names of the attributes for the super class Database.
	//
	private enum Attr {
		AGILITY				("Agility"),
		STRENGTH			("Strength"),
		INTELLIGENCE		("Intelligence"),
		ATTRACTIVENESS		("Attractiveness"),
		TRAMPLE				("Trample"),
		HANDLING			("Handling"),
		HORSENAME			("HorseName"),
		TIMEWHENMOUNTED		("TimeWhenMounted"),
		TIMEWHENWASHED		("TimeWhenWashed"),
		TIMEWHENGROOMED		("TimeWhenGroomed");
		
		
		private final String name;
		
		Attr(String name) {
			this.name = name;
		}

	}
	
	//
	// HorseDatabase() - (constructor) in this constructor we use the 
	// generic database object but give it the name it will be saved under.  
	//
	public HorseDatabase(JavaPlugin plugin) {
		super(plugin,"HorseData");
		this.plugin = plugin;
		// This either loads the database or comes back with a blank database
	}
	
	 //
	 // getAgility() - Sets the Agility value(int) or assigns a default value(defval) if no original value was found.
	 // setAgility() - Gets the Agility value(int) from Metadata.
	 // hasAgility() - Checks to see if there is a Agility value(int) stored in Metadata.
	 //
	 public Skill getAgility(Entity entity) {
		 if(!hasAgility(entity)) {
			 Skill defval = new Skill();
			 setAgility(entity, defval);
		 }
		 return getAttributeSkill(entity, Attr.AGILITY.name);
	 }
	 public void setAgility(Entity entity, Skill value) {
		 this.setAttribute(entity, Attr.AGILITY.name, value);
	 }
	 public boolean hasAgility(Entity entity) {
		 return hasAttribute(entity, Attr.AGILITY.name);
	 }

	 

	 //
	 // getStrength() - Sets the Strength value(int) or assigns a default value(defval) if no original value was found.
	 // setStrength() - Gets the Strength value(int) from Metadata.
	 // hasStrength() - Checks to see if there is a Strength value(int) stored in Metadata.
	 //
	 public Skill getStrength(Entity entity) {
		 if(!hasStrength(entity)) {
			 Skill defval = new Skill();
			 setStrength(entity, defval);
		 }
		 return getAttributeSkill(entity, Attr.STRENGTH.name);
	 }
	 public void setStrength(Entity entity, Skill value) {
		 this.setAttribute(entity, Attr.STRENGTH.name, value);
	 }
	 public boolean hasStrength(Entity entity) {
		 return hasAttribute(entity, Attr.STRENGTH.name);
	 }


	 //
	 // getIntelligence() - Sets the Intelligence value(int) or assigns a default value(defval) if no original value was found.
	 // setIntelligence() - Gets the Intelligence value(int) from Metadata.
	 // hasIntelligence() - Checks to see if there is a Intelligence value(int) stored in Metadata.
	 //
	 public Skill getIntelligence(Entity entity) {
		 if(!hasIntelligence(entity)) {
			 Skill defval = new Skill();
			 setIntelligence(entity, defval);
		 }
		 return getAttributeSkill(entity, Attr.INTELLIGENCE.name);
	 }
	 public void setIntelligence(Entity entity, Skill value) {
		 this.setAttribute(entity, Attr.INTELLIGENCE.name, value);
	 }
	 public boolean hasIntelligence(Entity entity) {
		 return hasAttribute(entity, Attr.INTELLIGENCE.name);
	 }


	 //
	 // getAttractiveness() - Sets the Attractiveness value(int) or assigns a default value(defval) if no original value was found.
	 // setAttractiveness() - Gets the Attractiveness value(int) from Metadata.
	 // hasAttractivenes() - Checks to see if there is a Attractiveness value(int) stored in Metadata.
	 //
	 public Skill getAttractiveness(Entity entity) {
		 if(!hasAttractiveness(entity)) {
			 Skill defval = new Skill();
			 setAttractiveness(entity, defval);
		 }
		 return getAttributeSkill(entity, Attr.ATTRACTIVENESS.name);
	 }
	 public void setAttractiveness(Entity entity, Skill value) {
		 this.setAttribute(entity, Attr.ATTRACTIVENESS.name, value);
	 }
	 public boolean hasAttractiveness(Entity entity) {
		 return hasAttribute(entity, Attr.ATTRACTIVENESS.name);
	 }
	 

	 //
	 // getTrample() - Sets the trample value(int) or assigns a default value(defval) if no original value was found.
	 // setTrample() - Gets the trample value(int) from Metadata.
	 // hasTrample() - Checks to see if there is a Trample value(int) stored in Metadata.
	 //
	 public Skill getTrample(Entity entity) {
		 if(!hasTrample(entity)) {
			 Skill defval = new Skill();
			 setTrample(entity, defval);
		 }
		 return getAttributeSkill(entity, Attr.TRAMPLE.name);
	 }
	 public void setTrample(Entity entity, Skill value) {
		 this.setAttribute(entity, Attr.TRAMPLE.name, value);
	 }
	 public boolean hasTrample(Entity entity) {
		 return hasAttribute(entity, Attr.TRAMPLE.name);
	 }
	 

	 //
	 // getHorseName() - Sets the HorseName value(String) or assigns a default value if no original value was found.
	 // setHorseName() - Gets the HorseName value(String) from Metadata.
	 // hasHorseName() - Checks to see if there is a HorseName value(String) stored in Metadata.
	 //
	 public String getHorseName(Entity entity) {
		 if(!hasHorseName(entity)) {
			 String defval = null;
			 setHorseName(entity, defval);
		 }
		 return getAttributeString(entity, Attr.HORSENAME.name);
	 }
	 public void setHorseName(Entity entity, String value) {
		 this.setAttribute(entity, Attr.HORSENAME.name, value);
	 }
	 public boolean hasHorseName(Entity entity) {
		 return hasAttribute(entity, Attr.HORSENAME.name);
	 }
	
	 //
	 // getHandling() - Sets the Handling value(int) or assigns a default value if 
	 //						no original value was found for a horses handling with a  specific player.
	 // setHandling() - Gets the Handling value(int) from metadata for the horse with a  specific player.
	 // hasHandling() - Checks to see if there is a Handling value(int) stored in metadata for this horse with the specified player.
	 //
	 public Skill getHandling(Entity entity, Player player) {
		 if(!hasHandling(entity, player)) {
			 Skill defval = new Skill();
			 setHandling(entity, player, defval);
		 }
		 return getAttributeSkill(entity, Attr.HANDLING.name, player.getName());
	 }
	 public void setHandling(Entity entity, Player player, Skill value) {
		 this.setAttribute(entity, Attr.HANDLING.name, player.getName(), value);
	 }
	 public boolean hasHandling(Entity entity, Player player) {
		 return hasAttribute(entity, Attr.HANDLING.name, player.getName());
	 }
	 public void horseDied(Entity horse) {
		 // TODO - need to deal with horse dying - should be removed from the database (file-based too)
		 // this.remove(horse);
	 }
	 //
	 // getTimeWhenMounted() - Gets the time as a long when the horse was mounted.
	 // getTimeWhenMounted() - Set time when horse was mounted.
	 // hasTimeWhenMounted() - checks to see if a value exists for TimeWhenMounted.
	 //
	 public long getTimeWhenMounted(Entity entity) {
		 if(!hasTimeWhenMounted(entity)) {
			 long defval = 0;
			 setTimeWhenMounted(entity, defval);
		 }
		 return getAttributeLong(entity, Attr.TIMEWHENMOUNTED.name);
	 }
	 public void setTimeWhenMounted(Entity entity, long value) {
		 this.setAttribute(entity, Attr.TIMEWHENMOUNTED.name, value);
	 }
	 public boolean hasTimeWhenMounted(Entity entity) {
		 return hasAttribute(entity, Attr.TIMEWHENMOUNTED.name);
	 }
	 
	 //
	 // getTimeWhenGroomed() - Gets the time as a long when the horse was mounted.
	 // getTimeWhenGroomed() - Set time when horse was mounted.
	 // hasTimeWhenGroomed() - checks to see if a value exists for TimeWhenMounted.
	 //
	 public long getTimeWhenGroomed(Entity entity) {
		 if(!hasTimeWhenGroomed(entity)) {
			 long defval = 0;
			 setTimeWhenGroomed(entity, defval);
		 }
		 return getAttributeLong(entity, Attr.TIMEWHENGROOMED.name);
	 }
	 public void setTimeWhenGroomed(Entity entity, long value) {
		 this.setAttribute(entity, Attr.TIMEWHENGROOMED.name, value);
	 }
	 public boolean hasTimeWhenGroomed(Entity entity) {
		 return hasAttribute(entity, Attr.TIMEWHENGROOMED.name);
	 }
	
	 //
	 // getTimeWhenGroomed() - Gets the time as a long when the horse was mounted.
	 // getTimeWhenGroomed() - Set time when horse was mounted.
	 // hasTimeWhenGroomed() - checks to see if a value exists for TimeWhenMounted.
	 //
	 public long getTimeWhenWashed(Entity entity) {
		 if(!hasTimeWhenWashed(entity)) {
			 long defval = 0;
			 setTimeWhenWashed(entity, defval);
		 }
		 return getAttributeLong(entity, Attr.TIMEWHENWASHED.name);
	 }
	 public void setTimeWhenWashed(Entity entity, long value) {
		 this.setAttribute(entity, Attr.TIMEWHENWASHED.name, value);
	 }
	 public boolean hasTimeWhenWashed(Entity entity) {
		 return hasAttribute(entity, Attr.TIMEWHENWASHED.name);
	 }
	 
	
}
